package jinyilw.tools.net.dev;

import java.io.IOException;
import java.io.InputStream;

public class PipedInputStream extends InputStream
{
	private final int[] data;
	private int write;
	private int read;
	private int available;

	public PipedInputStream(PipedOutputStream pout, int size) throws IOException
	{
		this.data = new int[size];
		pout.connect(this);
	}

	@Override
	public synchronized int available()
	{
		return this.available;
	}

	@Override
	public void close() throws IOException
	{
	}

	@Override
	public synchronized int read() throws IOException
	{
		if (this.available <= 0)
		{
			return -1;
		}
		if (this.read == this.write)
		{
			return -1;
		}

		this.available--;
		int value = this.data[this.read];
		this.read++;
		if (this.read >= this.data.length)
		{
			this.read = 0;
		}
		return value;
	}

	@Override
	public synchronized int read(byte[] ret, int off, int len)
			throws IOException
	{
		if (this.available <= 0)
		{
			return -1;
		}

		int count = 0;
		for (int i = off; i < off + len; i++)
		{
			int b = this.read();
			if (b == -1)
			{
				break;
			}
			count++;
			ret[i] = (byte) b;
		}

		return count;
	}

	protected synchronized void receive(int b) throws IOException
	{
		if (b < 0)
		{
			b = 256 + b;
		}
		data[write] = b;
		write++;
		if (write >= data.length)
		{
			write = 0;
		}
		if (write == read)
		{
			throw new IOException("Buffer overflow in NewPipedInputStream");
		}

		available++;
	}

	@Override
	public int read(byte[] b) throws IOException
	{
		return this.read(b, 0, b.length);
	}

	@Override
	public synchronized void reset() throws IOException
	{
		available = write = read = 0;
	}

	public void clear()
	{
		available = write = read = 0;
	}

}
